package com.rfid.transport;

import android.util.Log;

import com.rfid.api.GFunction;
import com.rfid.api.MonitorLogHelper;

import java.util.Arrays;

/*
  广州品创电子数据交换（UDP、串口）
 */
public class PCTransport extends CommTransport {
    byte[] m_recvbuf = new byte[1024];
    public int connectBluetoolth(String paramString)
    {
        return -3;
    }
    public int connectCom(String sPath, int m_baud, String sFrame, byte addr) {
        this.m_if = new Transport_SerialPort();
        Transport_SerialPort m_com = (Transport_SerialPort) this.m_if;
        this.m_remoteAddr.setNad(addr);
        int iret = m_com.Connect(sPath, m_baud, sFrame);
        if (iret == 0) {
            this.m_recvedBuffer = new RingBuffer(1024);
            this.m_bufferForRead = new byte[1024];
        }
        return iret;
    }



    public int connectNetClent(String paramString, int paramInt)
    {
        this.m_if = new Transport_UdpClient();
        paramInt = ((Transport_UdpClient)this.m_if).Connect(paramString, paramInt);
        if (paramInt == 0)
        {
            this.m_remoteAddr.setNad((byte)-1);
            this.m_recvedBuffer = new RingBuffer(1024);
            this.m_bufferForRead = new byte[1024];
        }
        return paramInt;
    }
    public int connectUsb(String paramString)
    {
        this.m_if =new Transport_Hid();
        int iret=((Transport_Hid)this.m_if).Connect(paramString);
        if (iret==0)
        {
            this.m_remoteAddr.setNad((byte)-1);
            this.m_recvedBuffer = new RingBuffer(1024);
            this.m_bufferForRead = new byte[1024];
        }
        return iret;
    }

    public int connectZTEK(int paramInt1, int paramInt2, String paramString, byte paramByte){return  -3;}

    private char crc16(byte[] pCrcData, int offset, int pLen)
    {
        int CRC = 61166;
        if (pLen==0)
        {
            return Character.MIN_VALUE;
        }
        for (int i = 0; i < pLen; i++) {
            CRC ^= pCrcData[i + offset]&0xFF;
            for (int j=0;j<8;j++)
            {
                if ((CRC &0x0001)!=0)
                {
                    CRC=(CRC>>1)^0x8408;
                }else {
                    CRC=(CRC>>1);
                }
            }
        }
        return  (char)CRC;
    }
    private BufferPack llSendframe = new BufferPack();
    protected int ll_send(byte[] buffer, int offset, int m_Size) {
        this.llSendframe.flush();
        //包头
        this.llSendframe.WriteData("AA");
        //长度
        this.llSendframe.WriteData((byte)(4 + m_Size));
        //地址
        this.llSendframe.WriteData(this.m_remoteAddr.getNad());
        //数据=命令码+数据内容
        this.llSendframe.WriteData(buffer, offset, m_Size);
        char crc16 = crc16(this.llSendframe.GetBuffer(), 1, this.llSendframe.getBufferLen() - 1);
        this.llSendframe.WriteData(crc16);
        String hex="Send:>>"+ GFunction.encodeHexStr(this.llSendframe.GetBuffer(),this.llSendframe.getBufferLen());
        MonitorLogHelper.Log().WriterLog(hex);
        Log.d("PCTransport SS:", GFunction.encodeHexStr(this.llSendframe.GetBuffer(),this.llSendframe.getBufferLen()));
        int ret= this.m_if.Send(this.llSendframe.GetBuffer(), 0, this.llSendframe.getBufferLen());
        if (ret != 0) return -2;
        return 0;
    }
    private BufferPack pllRecvFrame = new BufferPack();

    @Override
    public int recv(byte[] buf, Integer len, int flags) {
        return super.recv(buf, len, flags);
    }

    protected int ll_recv(BufferPack recvdata) {
        this.pllRecvFrame.flush();
        int ret = this.m_if.Receive(this.m_bufferForRead, 1024);

        if (ret > 0) this.m_recvedBuffer.PushData(this.m_bufferForRead, ret);
        else if (ret < 0) return -2;
        if (this.m_recvedBuffer.GetLength(-1, -1) > 0 && ParseFrame(this.pllRecvFrame) && this.pllRecvFrame.GetBuffer() != null)
        {
            if (this.m_remoteAddr.getNad() == this.pllRecvFrame.GetBuffer()[2] || this.m_remoteAddr.getNad() == -1) {
                Log.d("PCTransport RR:", GFunction.encodeHexStr(this.pllRecvFrame.GetBuffer()));
                String hex="Receive:<<"+ GFunction.encodeHexStr(this.pllRecvFrame.GetBuffer());
                MonitorLogHelper.Log().WriterLog(hex);

                recvdata.WriteData(this.pllRecvFrame.GetBuffer(), 3, this.pllRecvFrame.getBufferLen() - 5);
            }
            return this.pllRecvFrame.getBufferLen();
        }
        return 0;
    }
    protected int ll_recv1(BufferPack recvdata)
    {

        int result = -1;
        int rlen = 0;
        int readlen = 8;
        while (true)
        {
            readlen =8;
            this.pllRecvFrame.flush();
            while (true)
            {
                rlen = this.m_if.Receive(this.m_bufferForRead, 1024);
                if (rlen>0)
                {
                    this.m_recvedBuffer.PushData(this.m_bufferForRead,rlen);
                    if (this.m_recvedBuffer.GetLength(-1, -1) > 0 && ParseFrame(this.pllRecvFrame))
                    {

                    }else
                    {

                    }
                }
            }


        }
    }
    private boolean ParseFrame(BufferPack ppFrame) {
        int Poplen;
        boolean result = false;
        Frame_hdr hdr = new Frame_hdr();
        int startpos = -1;
        int CandidatePos = -1;
        while (true) {
            int ipos = this.m_recvedBuffer.SearchByte(startpos, (byte)170);
            if (ipos == -1) break;
            int nLen = this.m_recvedBuffer.GetLength(ipos, -1);
            if (nLen < 8) {
                if (CandidatePos == -1) CandidatePos = ipos;
                break;
            }
            byte[] byTmp = new byte[6];
            this.m_recvedBuffer.GetBufData(ipos, byTmp.length, byTmp);
            hdr.setSOF(byTmp[0]);
            hdr.setLen(byTmp[1]);
            hdr.setAddr(byTmp[2]);
            hdr.setCommand((char) (byTmp[3] | byTmp[4] << 8));
            if (nLen < hdr.getLen() + 1) {
                if (CandidatePos == -1) CandidatePos = ipos;
                startpos = this.m_recvedBuffer.GetNewPos(ipos, 1);
                continue;
            }
            if (hdr.getLen() < 7) {
                startpos = this.m_recvedBuffer.GetNewPos(ipos, 1);
                continue;
            }
            byte[] Tmpbuf = new byte[hdr.getLen() + 1];
            this.m_recvedBuffer.GetBufData(ipos, hdr.getLen() + 1, Tmpbuf);
            char chksum = crc16(Tmpbuf, 1, hdr.getLen() - 2);
            char chksum2 = (char) (Tmpbuf[1 + hdr.getLen() - 2] & 0xFF | Tmpbuf[1 + hdr.getLen() - 1] << 8 & 0xFF00);
            if (chksum != chksum2) {
                startpos = this.m_recvedBuffer.GetNewPos(ipos, 1);
                continue;
            }
            ppFrame.WriteData(Tmpbuf, 0, Tmpbuf.length);
            CandidatePos = this.m_recvedBuffer.GetNewPos(ipos, hdr.getLen() + 1);
            result = true;
            break;
        }
        if (CandidatePos == -1) Poplen = this.m_recvedBuffer.GetLength(-1, -1);
        else Poplen = this.m_recvedBuffer.GetLength(-1, CandidatePos);
        this.m_recvedBuffer.PopData(null, Poplen, null);
        return result;
    }
}
